
package eg.ci.mvn.service.demo.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import eg.ci.mvn.service.api.constant.ApiNo;
import eg.ci.mvn.service.api.model.BaseResponse;
import eg.ci.mvn.service.api.model.ErrorType;
import eg.ci.mvn.service.api.model.param.ScriptParam;
import eg.ci.mvn.service.core.config.git.GitRepositoryState;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 版本和git信息
 */
@Slf4j
@RestController
@Tag(name = ApiNo.VERSION_TEST)
public class VersionsController {

    @Operation(summary = ApiNo.VERSION_TEST_GET_VERSION, description = ApiNo.VERSION_TEST_GET_VERSION)
    @GetMapping(value = "version")
    public BaseResponse version() {
        return new BaseResponse<>(SpringUtil.getBean(GitRepositoryState.class), ErrorType.SUCCESS);
    }

    @Operation(summary = ApiNo.VERSION_TEST_JOB, description = ApiNo.VERSION_TEST_JOB)
    @Parameters({
            @Parameter(name = "jobName",example = "1",description = "名称",required = true,in = ParameterIn.QUERY),
            @Parameter(name = "operation",description = "操作",required = true,in= ParameterIn.QUERY),
            @Parameter(name = "args",description = "参数组",required = true,in= ParameterIn.QUERY)
    })
    @GetMapping(value = "job")
    public BaseResponse job(@RequestParam(value= "jobName", defaultValue ="memberJob") String jobName,
                            @RequestParam(value = "operation", defaultValue ="echo") String operation,
                            @RequestParam(value = "args", defaultValue = "[]") String arrays) {
        Object instance = SpringUtil.getBean(jobName);

        if(null != instance) {
            Method method = ReflectUtil.getMethodByName(instance.getClass(), operation);
            final Class<?>[] parameterTypes = method.getParameterTypes();
            JSONArray jsonArray = JSON.parseArray(arrays);
            List<Object> args = null;
            if( jsonArray.size() >= parameterTypes.length ) {
                String argsText = JSON.toJSONString(CollUtil.sub(jsonArray, 0 , parameterTypes.length));
                args = JSON.parseArray(argsText, parameterTypes);
            } else {
                final Class<?>[] parameterTypes2 = ArrayUtil.sub(parameterTypes, 0 , jsonArray.size());
                args = JSON.parseArray(arrays, parameterTypes2);
            }
            Object ret = ReflectUtil.invoke(instance, method, args.stream().toArray());

            return new BaseResponse<>(ErrorType.SUCCESS, "", ret);
        } else {
            return new BaseResponse<>(ErrorType.SUCCESS);
        }

    }

    @Operation(summary = ApiNo.VERSION_TEST_SCRIPT, description = ApiNo.VERSION_TEST_SCRIPT)
    @PostMapping(value = "script")
    public BaseResponse script(@RequestBody ScriptParam.RequestParam param) {
        //
        Object instance = SpringUtil.getBean(param.getName());

        if(null != instance) {
            Method method = ReflectUtil.getMethodByName(instance.getClass(), param.getOperation());
            final Class<?>[] parameterTypes = method.getParameterTypes();
            JSONArray jsonArray = JSON.parseArray(param.getCnt());
            List<Object> args = null;
            if( jsonArray.size() >= parameterTypes.length ) {
                String argsText = JSON.toJSONString(CollUtil.sub(jsonArray, 0 , parameterTypes.length));
                args = JSON.parseArray(argsText, parameterTypes);
            } else {
                final Class<?>[] parameterTypes2 = ArrayUtil.sub(parameterTypes, 0 , jsonArray.size());
                args = JSON.parseArray(param.getCnt(), parameterTypes2);
            }
            Object ret = ReflectUtil.invoke(instance, method, args.stream().toArray());

            return new BaseResponse<>(ErrorType.SUCCESS, "", ret);
        } else {
            return new BaseResponse<>(ErrorType.SUCCESS);
        }
    }
}
